package com.ebupt.service

import androidx.annotation.Keep
import com.blankj.utilcode.util.GsonUtils
import com.ebupt.common.net.model.DataResult
import com.ebupt.common.net.model.successed
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract

@Keep
data class NetRepo<T:Any>(var errorMsg:String,var errorCode:Int,var data:T)

/**
 * "courseId": 13,
"id": 150,
"name": "开发环境",
"order": 1,
"parentChapterId": 0,
"userControlSetTop": false,
"visible": 1
 */

@Keep
data class KnowledgeSystem(var courseId:Int,var id:Int,var name:String,
                            var order:Int,var parentChapterId:Int,
                            var userControlSetTop:String,
                            var visible:Int){
    override fun toString(): String {
        return "KnowledgeSystem(courseId=$courseId, id=$id, name='$name', order=$order, parentChapterId=$parentChapterId, userControlSetTop='$userControlSetTop', visible=$visible)"
    }
}





@OptIn(ExperimentalContracts::class)
inline fun<reified T:Any> NetRepo<T>.onBizOk(crossinline block:(code: Int, data: T?, message: String?)->Unit):NetRepo<T>{
    contract {
        callsInPlace(block,InvocationKind.AT_MOST_ONCE)
    }
    if (errorCode ==0){
        block.invoke(errorCode,data,errorMsg)
    }
    return this
}

@OptIn(ExperimentalContracts::class)
inline fun<reified T:Any> NetRepo<T>.onBizFail(crossinline block:(code: Int,  message: String?)->Unit):NetRepo<T>{
    contract {
        callsInPlace(block,InvocationKind.AT_MOST_ONCE)
    }
    if (errorCode ==0){
        block.invoke(errorCode,errorMsg)
    }
    return this
}




@OptIn(ExperimentalContracts::class)
inline fun<R> DataResult<R>.onSuccess(action:R.()->Unit):DataResult<R>{
    contract {
        callsInPlace(action,InvocationKind.AT_MOST_ONCE)
    }
    if (successed){
        action.invoke((this as DataResult.Success<R>).data)
    }
    return this
}


@OptIn(ExperimentalContracts::class)
inline fun<R> DataResult<R>.onFailure(action:(exception: Throwable)->Unit):DataResult<R>{
    contract {
        callsInPlace(action,InvocationKind.AT_MOST_ONCE)
    }
    if (this is DataResult.Error){
        action.invoke(exception)
    }
    return this
}